// 定义事件处理函数的类型
type EventHandler<T = any> = (...args: T[]) => void;

// 事件发射器类，实现事件的注册、触发和移除
class EventEmitter {
    // 存储事件与对应处理函数的映射
    private events: Map<string, Set<EventHandler>>;

    constructor() {
        this.events = new Map();
    }

    on<T = any>(event: string, handler: EventHandler<T>): void {
        if (!this.events.has(event)) {
            this.events.set(event, new Set());
        }
        
        this.events.get(event)!.add(handler);
    }

    off<T = any>(event: string, handler: EventHandler<T>): void {
        const handlers = this.events.get(event);
        
        if (handlers) {
            handlers.delete(handler);
            
            // 如果事件的处理函数集合为空，则移除该事件
            if (handlers.size === 0) {
                this.events.delete(event);
            }
        }
    }

    emit<T = any>(event: string, ...args: T[]): void {
        const handlers = this.events.get(event);
        
        if (handlers) {
            const handlersCopy = new Set(handlers);
            handlersCopy.forEach(handler => {
                handler(...args);
            });
        }
    }

    once<T = any>(event: string, handler: EventHandler<T>): void {
        const wrapper: EventHandler<T> = (...args) => {
            handler(...args);
            this.off(event, wrapper);
        };
        this.on(event, wrapper);
    }

    removeAllListeners(event?: string): void {
        if (event) {
            this.events.delete(event);
        } else {
            this.events.clear();
        }
    }

    listeners(event: string): EventHandler[] {
        return Array.from(this.events.get(event) || []);
    }
}

function demonstrateEventHandling() {
    const emitter = new EventEmitter();
    const greetHandler = (name: string) => {
        console.log(`Hello, ${name}!`);
    };

    const logHandler = (message: string) => {
        console.log(`Log: ${message}`);
    };

    emitter.on('greet', greetHandler);
    emitter.on('log', logHandler);
    
    emitter.once('onceEvent', () => {
        console.log('这个事件只会触发一次');
    });

    console.log('第一次触发事件:');
    emitter.emit('greet', 'TypeScript');
    emitter.emit('log', '事件处理示例');
    emitter.emit('onceEvent');

    console.log('第二次触发一次性事件（无输出）:');
    emitter.emit('onceEvent');

    emitter.off('greet', greetHandler);
    
    console.log('移除greet监听器后触发:');
    emitter.emit('greet', 'TypeScript');
    emitter.emit('log', '仍然可以触发');

    console.log('当前log事件的监听器数量:', emitter.listeners('log').length); 
}

demonstrateEventHandling();